#include <iostream>
#include <memory>
using namespace std; 

/*简单工厂模式*/
// class Fruit
// {
// public:
//     virtual void name()=0;//纯虚函数
// private:
// };

// class Apple:public Fruit//继承水果类
// {
// public:
//     void name() override//override表示对父类虚函数的重写操作
//     {
//         cout<<"我是一个apple\n";
//     }
// };

// class Banana:public Fruit//继承水果类
// {
// public:
//     void name() override//override表示对父类虚函数的重写操作
//     {
//         cout<<"我是一个Banana\n";
//     }
// };

// class FruitFactory
// {
// public:
// //返回的是一个水果对象shared_ptr<Fruit>
//     static shared_ptr<Fruit> create(const string&name)
//     {
//         if(name=="apple")
//         {
//             return make_shared<Apple>();//创建一个apple对象
//         }

//         else
//         {
//             return make_shared<Banana>();//创建一个Banana对象
//         }

//     }

// };

// int main()
// {
//     //将创建出来的对象交给智能指针
//     shared_ptr<Fruit>fruit=FruitFactory::create("apple");//创建一个apple对象
//     fruit->name();

//     fruit=FruitFactory::create("Banana");//创建一个Banana对象
//     fruit->name();
//     return 0;

// }

// /*工厂方法模式*/
// class Fruit
// {
// public:
//     virtual void name()=0;//纯虚函数
// private:
// };

// class Apple:public Fruit//继承水果类
// {
// public:
//     void name() override//override表示对父类虚函数的重写操作
//     {
//         cout<<"我是一个apple\n";
//     }
// };

// class Banana:public Fruit//继承水果类
// {
// public:
//     void name() override//override表示对父类虚函数的重写操作
//     {
//         cout<<"我是一个Banana\n";
//     }
// };

// class FruitFactory
// {
// public:
//     virtual shared_ptr<Fruit> create()=0;//纯虚函数
// };

// class AppleFactory:public FruitFactory//继承工厂类
// {
// public:
//     shared_ptr<Fruit> create()override//override表示对父类虚函数的重写操作
//     {
//         return make_shared<Apple>();//创建一个apple对象
//     }

// };

// class BananaFactory:public FruitFactory//继承工厂类
// {
// public:
//     shared_ptr<Fruit> create()override//override表示对父类虚函数的重写操作
//     {
//         return make_shared<Banana>();//创建一个apple对象
//     }
// };
// //一个产品对应一个工厂，一个工厂只生产一种产品
// int main()
// {
//     shared_ptr<FruitFactory>ff(new AppleFactory());//创建一个apple工厂对象
//     shared_ptr<Fruit>fruit=ff->create();//创建一个apple对象
//     fruit->name();
//     ff.reset(new BananaFactory());//创建一个Banana工厂对象
//     fruit=ff->create();
//     fruit->name();
//     return 0;
// }

/*抽象⼯⼚模式*/

class Fruit
{
public:
    virtual void name() = 0; // 纯虚函数
private:
};

class Apple : public Fruit // 继承水果类
{
public:
    void name() override // override表示对父类虚函数的重写操作
    {
        cout << "我是一个apple\n";
    }
};

class Banana : public Fruit // 继承水果类
{
public:
    void name() override // override表示对父类虚函数的重写操作
    {
        cout << "我是一个Banana\n";
    }
};

class Animal
{
public:
    virtual void name() = 0; // 纯虚函数
};

class Lamp : public Animal // 继承动物类
{
public:
    void name() override // override表示对父类虚函数的重写操作
    {
        cout << "我是一只山羊!!\n";
    }
};

class Dog : public Animal // 继承动物类
{
public:
    void name() override // override表示对父类虚函数的重写操作
    {
        cout << "我是一只小狗!!\n";
    }
};

// 超级工厂
class Factory // 通过这个工厂类派生出对应类型的产品类
{
public:
    virtual shared_ptr<Fruit> getFruit(const string &name) = 0;   // 水果类的纯虚函数
    virtual shared_ptr<Animal> getAnimal(const string &name) = 0; // 水果类的纯虚函数
};

// 水果工厂
class FruitFactory : public Factory // 继承工厂类
{
public:
    shared_ptr<Fruit> getFruit(const string &name) override // override表示对父类虚函数的重写操作
    {
        // 根据不同的水果来产生水果对象
        if (name == "apple")
        {
            return make_shared<Apple>(); // 创建一个apple对象
        }

        else
        {
            return make_shared<Banana>(); // 创建一个Banana对象
        }
    }
    shared_ptr<Animal> getAnimal(const string &name) override // 水果类的纯虚函数
    {
        return shared_ptr<Animal>(); // 因为这个是水果工厂，所以没有动物，所以我们返回一个空的智能指针
    }
};

// 动物工厂
class AnimalFactory : public Factory // 继承工厂类
{
public:
    shared_ptr<Fruit> getFruit(const string &name) override // override表示对父类虚函数的重写操作
    {
        return shared_ptr<Fruit>(); // 因为这个是动物工厂，所以没有水果，所以我们返回一个空的智能指针
    }
    shared_ptr<Animal> getAnimal(const string &name) override // 水果类的纯虚函数
    {
        if (name == "小狗")
        {
            return make_shared<Dog>(); // 创建一个Dog对象
        }

        else
        {
            return make_shared<Lamp>(); // 创建一个Lamp对象
        }
    }
};

//工厂生产者
class FactoryProducer
{
public:
    static shared_ptr<Factory> create(const string &name) // 根据不同的类型来产生不同的工厂对象
    {
        if(name=="水果工厂")
        {
            return make_shared<FruitFactory>(); // 创建一个水果工厂对象
        }
        else
        {
            return make_shared<AnimalFactory>(); // 创建一个动物工厂对象
        }
    }
};

// 一个产品对应一个工厂，一个工厂只生产一种产品
int main()
{
    shared_ptr<Factory> ff = FactoryProducer::create("水果工厂"); // 创建一个水果工厂对象
    shared_ptr<Fruit> fruit = ff->getFruit("apple"); // 创建一个apple对象
    fruit->name();
    fruit=ff->getFruit("Banana"); // 创建一个Banana对象
    fruit->name();
    

    shared_ptr<Factory> factory = FactoryProducer::create("动物"); // 创建一个水果工厂对象
    shared_ptr<Fruit> animal = factory->getFruit("小狗"); // 创建一个apple对象
    animal->name();
    animal=factory->getFruit("山羊"); // 创建一个Banana对象
    animal->name();

    return 0;
}